use std::cell::RefCell;
use std::thread;

thread_local! {
    static COUNTER: RefCell<u32> = RefCell::new(0);
    static BUFFER: RefCell<String> = RefCell::new(String::new());
}

fn increment_and_log(step: u32) {
    COUNTER.with(|c| {
        let mut counter = c.borrow_mut();
        *counter += step;
        println!("Thread {:?}: COUNTER = {}", thread::current().id(), *counter);

        BUFFER.with(|b| {
            let mut buf = b.borrow_mut();
            buf.push_str(&format!("+{}", step));
            println!("Thread {:?}: BUFFER = '{}'", thread::current().id(), buf);
        });
    });
}

fn main() {
    let handles: Vec<_> = (0..3).map(|i| {
        thread::spawn(move || {
            println!("Thread {:?} started.", thread::current().id());
            increment_and_log(1);
            increment_and_log(2);
            increment_and_log(i + 1); // 每个线程略有不同
        })
    }).collect();

    for h in handles {
        h.join().unwrap();
    }

    // 主线程也访问一次
    increment_and_log(10);
}